%{
/*
 * HackSQL
 * Copyright (C) 2008-2009
 *
 * Authors: Felipe Nascimento Silva Pena
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $Id: hs_sql_scanner.l 21 2009-03-02 15:55:20Z felipensp $
 */

#include "hs_parser_common.h"
#include "hs_sql_parser.h"
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

%}

%option noyywrap
%option bison-bridge
%option case-insensitive

NUMBER [0-9]
NAME [a-z_][a-z0-9_]*
WHITESPACE [ \t\r\n]
SPECIAL ["'%&()*+,-.:;><=?/]

%%

{WHITESPACE}+ {
	/* Ignore */ ;
}

"||" {
	return T_OP_CONCAT;
}

"=" {
	return T_OP_EQUAL;
}

"<>" {
	return T_OP_NOT_EQUAL;
}

"<=" {
	return T_OP_LESS_THAN_OR_EQUAL;
}

">=" {
	return T_OP_GREATER_THAN_OR_EQUAL;
}

">" {
	return T_OP_GREATER_THAN;
}

"<" {
	return T_OP_LESS_THAN;
}

{SPECIAL} {
	return yytext[0];
}

{NUMBER}+ {
	return T_NUMBER;
}

"CREATE" {
	return T_CREATE;
}

"TABLE" {
	return T_TABLE;
}

"INSERT" {
	return T_INSERT;
}

"AUTHORIZATION" {
	return T_AUTHORIZATION;
}

"IDENTITY" {
	return T_IDENTITY;
}

"DESC" {
	return T_DESC;
}

"EXTERNAL" {
	return T_EXTERNAL;
}

"PAD" {
	return T_PAD;
}

"SPACE" {
	return T_SPACE;
}

"GET" {
	return T_GET;
}

"INTO" {
	return T_INTO;
}

"PRIMARY" {
	return T_PRIMARY;
}

"KEY" {
	return T_KEY;
}

"NO" {
	return T_NO;
}

"ACTION" {
	return T_ACTION;
}

"SELECT" {
	return T_SELECT;
}

"MODULE" {
	return T_MODULE;
}

"ASSERTION" {
	return T_ASSERTION;
}

"BETWEEN" {
	return T_BETWEEN;
}

"CHECK" {
	return T_CHECK;
}

"CORRESPONDING" {
	return T_CORRESPONDING;
}

"BY" {
	return T_BY;
}

"DATE" {
	return T_DATE;
}

"TIME" {
	return T_TIME;
}

"TIMESTAMP" {
	return T_TIMESTAMP;
}

"VARYING" {
	return T_VARYING;
}

"BIT" {
	return T_BIT;
}

"CONSTRAINT" {
	return T_CONSTRAINT;
}

"INNER" {
	return T_INNER;
}

"DELETE" {
	return T_DELETE;
}

"ROWS" {
	return T_ROWS;
}

"PRESERVE" {
	return T_PRESERVE;
}

"ON COMMIT" {
	return T_ON_COMMIT;
}

"TEMPORARY" {
	return T_TEMPORARY;
}

"LOCAL" {
	return T_LOCAL;
}

"GLOBAL" {
	return T_GLOBAL;
}

"JOIN" {
	return T_JOIN;
}

"ON" {
	return T_ON;
}

"LEFT" {
	return T_LEFT;
}

"RIGHT" {
	return T_RIGHT;
}

"WITH" {
	return T_WITH;
}

"CHECK OPTION" {
	return T_CHECK_OPTION;
}

"CASCADED" {
	return T_CASCADED;
}

"INITIALLY" {
	return T_INITIALLY;
}

"IMMEDIATE" {
	return T_IMMEDIATE;
}

"DEFERRED" {
	return T_DEFERRED;
}

"DEFERRABLE" {
	return T_DEFERRABLE;
}

"FULL" {
	return T_FULL;
}

"CHARACTER" {
	return T_CHARACTER;
}

"CHAR" {
	return T_CHAR;
}

"VARCHAR" {
	return T_VARCHAR;
}

"DEC" {
	return T_DEC;
}

"SMALLINT" {
	return T_SMALLINT;
}

"INTEGER" {
	return T_INTEGER;
}

"INT" {
	return T_INT;
}

"TO" {
	return T_TO;
}

"INTERVAL" {
	return T_INTERVAL;
}

"SECOND" {
	return T_SECOND;
}

"HOUR" {
	return T_HOUR;
}

"MINUTE" {
	return T_MINUTE;
}

"MONTH" {
	return T_MONTH;
}

"DAY" {
	return T_DAY;
}

"DECIMAL" {
	return T_DECIMAL;
}

"REAL" {
	return T_REAL;
}

"DOUBLE" {
	return T_DOUBLE;
}

"FLOAT" {
	return T_FLOAT;
}

"COLLATION" {
	return T_COLLATION;
}

"DOMAIN" {
	return T_DOMAIN;
}

"OUTER" {
	return T_OUTER;
}

"UNION" {
	return T_UNION;
}

"SCHEMA" {
	return T_SCHEMA;
}

"VIEW" {
	return T_VIEW;
}

"LIKE" {
	return T_LIKE;
}

"IN" {
	return T_IN;
}

"CURRENT USER" {
	return T_CURRENT_USER;
}

"OPTION" {
	return T_OPTION;
}

"CASCADE" {
	return T_CASCADE;
}

"RESTRICT" {
	return T_RESTRICT;
}

"SESSION USER" {
	return T_SESSION_USER;
}

"USER" {
	return T_USER;
}

"DESCRIBE" {
	return T_DESCRIBE;
}

"SYSTEM USER" {
	return T_SYSTEM_USER;
}

"NULL" {
	return T_NULL;
}

"DEFAULT" {
	return T_DEFAULT;
}

"TRANSACTION" {
	return T_TRANSACTION;
}

"VALUES" {
	return T_VALUES;
}

"ALL" {
	return T_ALL;
}

"EXCEPT" {
	return T_EXCEPT;
}

"INTERSECT" {
	return T_INTERSECT;
}

"NOT" {
	return T_NOT;
}

"IS" {
	return T_IS;
}

"OR" {
	return T_OR;
}

"DISTINCT" {
	return T_DISTINCT;
}

"AS" {
	return T_AS;
}

"GROUP" {
	return T_GROUP;
}

"COLLATE" {
	return T_COLLATE;
}

"HAVING" {
	return T_HAVING;
}

"FROM" {
	return T_FROM;
}

"WHERE" {
	return T_WHERE;
}

"FOR" {
	return T_FOR;
}

"UPPER" {
	return T_UPPER;
}

"LOWER" {
	return T_LOWER;
}

"DROP" {
	return T_DROP;
}

"ALTER" {
	return T_ALTER;
}

"ADD" {
	return T_ADD;
}

"COLUMN" {
	return T_COLUMN;
}

"TRIM" {
	return T_TRIM;
}

"USING" {
	return T_USING;
}

"LEADING" {
	return T_LEADING;
}

"TRAILING" {
	return T_TRAILING;
}

"BOTH" {
	return T_BOTH;
}

"POSITION" {
	return T_POSITION;
}

"AT" {
	return T_AT;
}

"EXTRACT" {
	return T_EXTRACT;
}

"TIMEZONE" {
	return T_TIMEZONE;
}

"TIMEZONE_HOUR" {
	return T_TIMEZONE_HOUR;
}

"TIMEZONE_MINUTE" {
	return T_TIMEZONE_MINUTE;
}

"CHAR_LENGTH" {
	return T_CHAR_LENGTH;
}

"CHARACTER_LENGTH" {
	return T_CHARACTER_LENGTH;
}

"BIT_LENGTH" {
	return T_BIT_LENGTH;
}

"OCTET_LENGTH" {
	return T_OCTET_LENGTH;
}

"TRANSLATE" {
	return T_TRANSLATE;
}

"CONVERT" {
	return T_CONVERT;
}

"SUBSTRING" {
	return T_SUBSTRING;
}

"INDICATOR" {
	return T_INDICATOR;
}

"CAST" {
	return T_CAST;
}

"COALESCE" {
	return T_COALESCE;
}

"NULLIF" {
	return T_NULLIF;
}

"COUNT" {
	return T_COUNT;
}

"END" {
	return T_END;
}

"BOOL" {
	return T_BOOL;
}

"GRANT" {
	return T_GRANT;
}

"PUBLIC" {
	return T_PUBLIC;
}

"TRANSLATION" {
	return T_TRANSLATION;
}

"ALL PRIVILEGES" {
	return T_ALL_PRIVILEGES;
}

"REFERENCES" {
	return T_REFERENCES;
}

"USAGE" {
	return T_USAGE;
}

"BLOB" {
	return T_BLOB;
}

"UPDATE" {
	return T_UPDATE;
}

"SET" {
	return T_SET;
}

"CURRENT" {
	return T_CURRENT;
}

"OF" {
	return T_OF;
}

"CASE" {
	return T_CASE;
}

"ELSE" {
	return T_ELSE;
}

"WHEN" {
	return T_WHEN;
}

"THEN" {
	return T_THEN;
}

"MIN" {
	return T_MIN;
}

"SUM" {
	return T_SUM;
}

"AVG" {
	return T_AVG;
}

"MAX" {
	return T_MAX;
}

"UNIQUE" {
	return T_UNIQUE;
}

"OVERLAPS" {
	return T_OVERLAPS;
}

"VALUE" {
	return T_VALUE;
}

"EXISTS" {
	return T_EXISTS;
}

"MATCH" {
	return T_MATCH;
}

"PARTIAL" {
	return T_PARTIAL;
}

"ESCAPE" {
	return T_ESCAPE;
}

"COMMIT" {
	return T_COMMIT;
}

"ROLLBACK" {
	return T_ROLLBACK;
}

"WORK" {
	return T_WORK;
}

"ISOLATION" {
	return T_ISOLATION;
}

"LEVEL" {
	return T_LEVEL;
}

"READ" {
	return T_READ;
}

"ONLY" {
	return T_READ;
}

"WRITE" {
	return T_WRITE;
}

"DIAGNOSTICS" {
	return T_DIAGNOSTICS;
}

"SIZE" {
	return T_SIZE;
}

"UNCOMMITTED" {
	return T_UNCOMMITTED;
}

"COMMITTED" {
	return T_COMMITTED;
}

"REPEATABLE" {
	return T_REPEATABLE;
}

"CURRENT_DATE" {
	return T_CURRENT_DATE;
}

"CURRENT_TIMESTAMP" {
	return T_CURRENT_TIMESTAMP;
}

"CURRENT_TIME" {
	return T_CURRENT_TIME;
}

"TRUE" {
	return T_TRUE;
}

"FALSE" {
	return T_FALSE;
}

"SERIALIZABLE" {
	return T_SERIALIZABLE;
}

{NAME} {
	return T_STRING;
}

. {
	return T_UNKNOWN;
}

%%

void yyerror(int socket, const char *message)
{
	send(socket, message, strlen(message), 0);
}

int hs_parser_query(int socket, const char *query)
{	
	YY_BUFFER_STATE buffer;
	int ret;
	
	buffer = yy_scan_string(query);
	ret = yyparse(socket);	
	yy_delete_buffer(buffer);
	
	return ret;
}

/*
int main(int argc, char **argv)
{
#if DEBUG
	hs_parser_query(argv[1]);
#endif
	return 0;
}
*/
